<template>
  <a-spin :spinning="confirmLoading">
    <j-form-container :disabled="formDisabled">
      <!-- 主表单区域 -->
      <a-form-model ref="form" :model="model" :rules="validatorRules" slot="detail">
        <span
          style="color: red;">"说明：1、根据院办发【2019】73号文件转发黑垦局办文【2019】72号文件规定组织培训的工作人员控制在参训人员数量的5%最多不超过10人。综合定额400元，场地、资料费、交通费70元/人天
          、伙食费110元、住宿费200元、其它费20元，各项费用之间可以调剂使用。培训类别是二类
          ，师资费在综合定额标准外单独核算，讲课费副高每学时不超500元，正高每学时不超1000元，院士、全国知名专家每学时不超1500元，每半天最多按4学时算。
          2
          、根据黑财规审〔2018]25号文件规定会议费管理,三四类会议会期不应超过两天，报道不应超过1天，我院可召开四类会议。四类会议参会人员不得超过150人，工作人员应在参会人数5%以内。会议费综合定额350元，伙食费110元、住宿费170元、其它费70元，各项费用之间可以调剂使用。"
        </span>
        <span style="color: red;">说明：单位：元
        </span>
        <a-row>
          <a-col :xs="12" :sm="12">
            <a-form-model-item label="年度" :labelCol="labelCol" :wrapperCol="wrapperCol" prop="year">
              <j-dict-select-tag type="list" v-model="model.year" dictCode="year" placeholder="请选择年度"
                @change="handleYearChange" />
            </a-form-model-item>
          </a-col>
        </a-row>
      </a-form-model>
    </j-form-container>
    <!-- 子表单区域 -->
    <a-tabs v-model="activeKey" @change="handleChangeTabs">
      <a-tab-pane tab="举办会议和培训计划表" :key="refKeys[0]" :forceRender="true">
        <j-editable-table :ref="refKeys[0]" :loading="cwJbhyhpxjhbTable.loading" :columns="cwJbhyhpxjhbTable.columns"
          :dataSource="cwJbhyhpxjhbTable.dataSource" :maxHeight="300" :disabled="formDisabled" :rowNumber="true"
          :rowSelection="true" :actionButton="true" @valueChange="handleTableValueChange" />
      </a-tab-pane>
    </a-tabs>
  </a-spin>
</template>

<script>
import { mapState } from 'vuex'
import { FormTypes, getRefPromise, VALIDATE_NO_PASSED } from '@/utils/JEditableTableUtil'
import { JEditableTableModelMixin } from '@/mixins/JEditableTableModelMixin'
import { validateDuplicateValue } from '@/utils/util'
import { getAction } from '@/api/manage'

export default {
  name: 'CwJbhyhpxjhbTjForm',
  mixins: [JEditableTableModelMixin],
  components: {},
  data() {
    return {
      labelCol: {
        xs: { span: 24 },
        sm: { span: 5 },
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 16 },
      },
      model: { year: '' }, // 初始为空，由watch同步全局年度
      validatorRules: {
        year: [
          { required: true, message: '请输入年度!' },
        ],
        unit: [
          { required: true, message: '请输入单位!' },
        ],
      },
      addDefaultRowNum: 1,
      refKeys: ['cwJbhyhpxjhb'],
      tableKeys: ['cwJbhyhpxjhb'],
      activeKey: 'cwJbhyhpxjhb',
      confirmLoading: false,
      // 举办会议和培训计划表
      cwJbhyhpxjhbTable: {
        loading: false,
        dataSource: [],
        columns: [
          {
            title: '内容',
            key: 'content',
            type: FormTypes.select,
            dictCode: "content",
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '会议、培训名称',
            key: 'conference',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '召开理由',
            key: 'zkly',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '会议类别',
            key: 'typeOfMeeting',
            type: FormTypes.select,
            dictCode: "type_of_meeting",
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          // {
          //   title: '会议类别',
          //   key: 'typeOfMeeting',
          //   type: FormTypes.input,
          //   width: "200px",
          //   placeholder: '请输入${title}',
          //   defaultValue: '',
          //   validateRules: [{ required: true, message: '${title}不能为空' }],
          // },
          {
            title: '召开时间',
            key: 'meetingTime',
            type: FormTypes.date,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '会议、培训地点',
            key: 'meeting',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '会议/培训主要内容',
            key: 'pxzynr',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
          {
            title: '参加人数',
            key: 'numberOfParticipants',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ pattern: "z", message: "${title}格式不正确请输入整数" }],
          },
          {
            title: '工作人数',
            key: 'gzrs',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
            validateRules: [{ pattern: "z", message: "${title}格式不正确请输入整数" }],
          },
          {
            title: '宿费',
            key: 'sf',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '宿费标准',
            key: 'sfbz',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '印刷费',
            key: 'printingExpenses',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '印刷费标准 ',
            key: 'ysfbz',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '伙食费',
            key: 'boardWages',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '伙食费标准',
            key: 'hsfbz',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '交通费',
            key: 'carFare',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '交通费标准',
            key: 'jtfbz',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '资料费',
            key: 'informationFee',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '资料费标准',
            key: 'clfbz',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '师资费',
            key: 'szf',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          {
            title: '场地费',
            key: 'siteFees',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '0.0',
            validateRules: [
              {
                // 修改后的正则：仅允许非负数字，支持整数或最多2位小数
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确，仅支持非负整数或最多2位小数"
              }
            ],
          },
          // 新增：经费合计列（关键）
          {
            title: '经费合计（元）',
            key: 'totalFund',
            type: FormTypes.input,
            width: "200px",
            placeholder: '自动计算',
            defaultValue: '0.00',
            disabled: true, // 禁止手动编辑
            validateRules: [
              {
                pattern: /^\d+(\.\d{1,2})?$/,
                message: "${title}格式不正确"
              }
            ]
          },
          {
            title: '备注',
            key: 'remark',
            type: FormTypes.input,
            width: "200px",
            placeholder: '请输入${title}',
            defaultValue: '',
          },
        ]
      },
      url: {
        add: "/cw/cwJbhyhpxjhbTj/add",
        edit: "/cw/cwJbhyhpxjhbTj/edit",
        cwJbhyhpxjhb: {
          list: '/cw/cwJbhyhpxjhbTj/queryCwJbhyhpxjhbByMainId'
        },
        getByYear: '/cw/cwJbhyhpxjhbTj/list' // 复用体检表的年度查询接口，后续可自行修改
      },
      calcTimer: null, // 关键：用于防抖计算
      isManualChange: false // 标记是否手动修改过表单年度
    }
  },
  props: {
    disabled: {
      type: Boolean,
      default: false,
      required: false
    },
    scene: { // 接收 Modal 传递的场景值
      type: String,
      default: ''
    }
  },
  computed: {
    formDisabled() {
      return this.disabled
    },
    ...mapState({ globalYear: state => state.app.globalYear })
  },
  watch: {
    // 监听全局年度变化，同步到表单（仅当未手动修改时）
    globalYear(newVal) {
      if (!this.isManualChange) {
        this.model.year = newVal
        // 可选：自动触发年度查询，解开注释即可
        // this.handleYearChange(newVal)
      }
    },
    // 监听表单年度变化，标记是否手动修改
    'model.year'(newVal, oldVal) {
      if (oldVal && newVal !== this.globalYear) {
        this.isManualChange = true // 手动修改后，不再同步全局年度
      }
    }
  },
  created() {
    // 初始化时同步全局年度
    this.model.year = this.globalYear

    const scene = this.scene; // 接收 Modal 传递的 scene（add/edit）
    this.currentScene = scene; // 存储到本地变量，后续复用
    console.log(scene)
    if (scene=='add'){
      this. handleYearChange(this.model.year)
    }
  },
  methods: {
    // 1. 统一监听表格值变化（和成功代码结构一致）
    handleTableValueChange({ row, column, value }) {
      console.log("表格值变化：", "列名=", column.key, "新值=", value, "当前行=", row);

      // 防抖避免频繁计算
      if (this.calcTimer) {
        clearTimeout(this.calcTimer);
      }

      // 仅当修改7个费用字段时，触发合计计算
      const feeKeys = ['sf', 'printingExpenses', 'boardWages', 'carFare', 'informationFee', 'szf', 'siteFees'];
      if (feeKeys.includes(column.key)) {
        this.calcTimer = setTimeout(() => {
          this.calcTotalFund(row); // 计算经费合计
        }, 50);
      }
    },

    // 2. 计算经费合计（7个费用相加）
    calcTotalFund(row) {
      console.log("触发经费合计计算：", "行=", row);

      if (!row) {
        console.warn("行数据为空，无法计算");
        return;
      }

      try {
        // 定义7个费用字段的key和默认值
        const feeConfig = [
          { key: 'sf', default: '0.0' }, // 宿费
          { key: 'printingExpenses', default: '0.0' }, // 印刷费
          { key: 'boardWages', default: '0.0' }, // 伙食费
          { key: 'carFare', default: '0.0' }, // 交通费
          { key: 'informationFee', default: '0.0' }, // 资料费
          { key: 'szf', default: '0.0' }, // 师资费
          { key: 'siteFees', default: '0.0' } // 场地费
        ];

        // 累加所有费用（安全解析数字）
        let total = 0;
        feeConfig.forEach(({ key, default: def }) => {
          const feeStr = String(row[key] || def).trim();
          const fee = this.safeParseNumber(feeStr);
          total += fee;
        });

        // 保留2位小数（四舍五入）
        const totalFund = Math.round(total * 100) / 100;
        if (isNaN(totalFund)) {
          console.error("计算结果为NaN，跳过更新");
          return;
        }
        const totalFundStr = totalFund.toFixed(2);
        console.log("经费合计结果：", totalFundStr);

        // 更新表格中的合计字段
        this.updateTotalFundInTable(row, totalFundStr);

      } catch (error) {
        console.error("计算经费合计时发生错误：", error);
      }
    },

    // 3. 安全解析数字（复用成功代码）
    safeParseNumber(str) {
      if (!str || typeof str !== 'string') return 0;
      const cleanStr = str.replace(/[^\d.-]/g, '');
      const num = parseFloat(cleanStr);
      return isNaN(num) ? 0 : Math.max(0, num); // 确保非负数
    },

    // 4. 更新表格中的经费合计（适配当前表格数据源）
    updateTotalFundInTable(row, totalFundStr) {
      const tableRef = this.$refs[this.refKeys[0]];
      if (!tableRef) {
        console.error("表格引用不存在");
        return;
      }

      // 方法1：使用表格setValues API（推荐）
      if (tableRef.setValues) {
        tableRef.setValues([{
          rowKey: row.id || row._rowKey, // 适配行标识
          values: { totalFund: totalFundStr }
        }]);
      }
      // 方法2：使用setCellValue（备选）
      else if (tableRef.setCellValue) {
        const rowIndex = this.cwJbhyhpxjhbTable.dataSource.findIndex(
          item => item.id === row.id || item._rowKey === row._rowKey
        );
        if (rowIndex !== -1) {
          tableRef.setCellValue(rowIndex, 'totalFund', totalFundStr);
        }
      }

      // 同步更新dataSource（确保数据一致性）
      this.$nextTick(() => {
        const dataIndex = this.cwJbhyhpxjhbTable.dataSource.findIndex(
          item => item.id === row.id || item._rowKey === row._rowKey
        );
        if (dataIndex !== -1) {
          this.$set(this.cwJbhyhpxjhbTable.dataSource[dataIndex], 'totalFund', totalFundStr);
        }
      });
    },

    // 5. 新增行初始化（适配当前表格）
    addBefore() {
      this.cwJbhyhpxjhbTable.dataSource = [];
      this.$nextTick(() => {
        const defaultRow = {
          id: Date.now().toString(), // 生成唯一行ID
          // 7个费用字段默认值
          sf: '0.0',
          printingExpenses: '0.0',
          boardWages: '0.0',
          carFare: '0.0',
          informationFee: '0.0',
          szf: '0.0',
          siteFees: '0.0',
          totalFund: '0.00', // 合计默认值
          // 其他字段保持默认空值...
        };
        this.cwJbhyhpxjhbTable.dataSource.push(defaultRow);
        this.calcTotalFund(defaultRow); // 初始化计算合计
      });
    },

    // 6. 编辑回显后计算合计
    editAfter() {
      this.$nextTick(() => {
        // 回显数据后计算所有行合计
        this.cwJbhyhpxjhbTable.dataSource.forEach(row => {
          this.calcTotalFund(row);
        });
      });
      if (this.model.id) {
        let params = { id: this.model.id }
        getAction(this.url.cwJbhyhpxjhb.list, params).then(res => {
          if (res.success) {
            this.cwJbhyhpxjhbTable.dataSource = res.result.records || [];
            // 数据加载完成后计算所有行合计
            this.$nextTick(() => {
              this.cwJbhyhpxjhbTable.dataSource.forEach(row => {
                this.calcTotalFund(row);
              });
            });
          }
        }).finally(() => {
          this.cwJbhyhpxjhbTable.loading = false
        })
      }
    },
    getAllTable() {
      let values = this.tableKeys.map(key => getRefPromise(this, key))
      return Promise.all(values)
    },
    // editAfter() {
    //   this.$nextTick(() => {
    //   })
    //   if (this.model.id) {
    //     let params = { id: this.model.id }
    //     getAction(this.url.cwJbhyhpxjhb.list, params).then(res => {
    //       if (res.success) {
    //         this.cwJbhyhpxjhbTable.dataSource = res.result.records || []
    //       }
    //     }).finally(() => {
    //       this.cwJbhyhpxjhbTable.loading = false
    //     })
    //   }
    // },
    validateSubForm(allValues) {
      return new Promise((resolve, reject) => {
        Promise.all([]).then(() => {
          resolve(allValues)
        }).catch(e => {
          if (e.error === VALIDATE_NO_PASSED) {
            this.activeKey = e.index == null ? this.activeKey : this.refKeys[e.index]
          } else {
            console.error(e)
          }
        })
      })
    },
    classifyIntoFormData(allValues) {
      let main = Object.assign(this.model, allValues.formValue)
      return {
        ...main,
        cwJbhyhpxjhbList: allValues.tablesValue[0].values,
      }
    },
    validateError(msg) {
      this.$message.error(msg)
    },
    close() {
      this.visible = false
      this.$emit('close')
      if (this.$refs.form) {
        this.$refs.form.clearValidate();
      }
    },
    async handleYearChange(year) {
      // 清空逻辑：未选择年度时，保留单位，清空其他数据
      if (!year) {
        this.model = { unit: this.model.unit }
        this.cwJbhyhpxjhbTable.dataSource = []
        return
      }

      // 加载状态：主表+子表同时加载
      this.confirmLoading = true
      this.cwJbhyhpxjhbTable.loading = true

      try {
        // 调用年度查询接口
        const yearResponse = await getAction(this.url.getByYear, { year })

        if (yearResponse.success && yearResponse.result.records.length > 0) {
          const mainRecord = yearResponse.result.records[0]
          // 主表数据回显：保留用户已选的unit和year，合并接口返回的其他字段
          this.model = {
            ...this.model,
            ...mainRecord
          }

          // 使用返回的mainId调用子表列表接口
          if (mainRecord.id) {
            const subResponse = await getAction(this.url.cwJbhyhpxjhb.list, {
              id: mainRecord.id
            })

            if (subResponse.success) {
              this.cwJbhyhpxjhbTable.dataSource = subResponse.result.records || []
            } else {
              this.$message.warning('获取会议培训表数据失败：' + (subResponse.message || '未知错误'))
              this.cwJbhyhpxjhbTable.dataSource = []
            }
          } else {
            this.$message.warning('未获取到关联ID，无法加载会议培训数据')
            this.cwJbhyhpxjhbTable.dataSource = []
          }
        } else {
          // 接口返回失败（如无数据），显示警告并清空子表
          this.$message.warning(yearResponse.message || '该年度暂无数据')
          this.cwJbhyhpxjhbTable.dataSource = []
          this.model.id = undefined;

        }
      } catch (error) {
        // 异常处理
        console.error('查询接口异常：', error)
        this.$message.error('查询失败，请刷新页面重试或联系管理员')
        this.cwJbhyhpxjhbTable.dataSource = []
      } finally {
        // 关闭加载状态（无论成功/失败）
        this.confirmLoading = false
        this.cwJbhyhpxjhbTable.loading = false
      }
    }
  }
}
</script>

<style scoped></style>